package com.wj.controller;

import com.wj.domain.param.BookParam;
import com.wj.domain.vo.*;
import com.wj.service.*;
import com.wj.tool.common.bean.ChapterReturnVO;
import com.wj.tool.common.exception.SelfException;
import com.wj.tool.common.utils.DeviceUtil;
import com.wj.tool.common.utils.StringUtils;
import com.wj.tool.common.utils.paging.PageUtil;
import com.wj.tool.common.utils.paging.Paging;
import com.wj.tool.common.utils.paging.QueryParameters;
import com.wj.tool.common.utils.paging.QueryResults;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

@Controller
@Slf4j
public class BookController {

    @Resource
    private BookService bookService;

    @Resource
    private ChapterService chapterService;

    @Resource
    private ChapterContentService chapterContentService;

    @Resource
    private BookShelfService bookShelfService;

    @Resource
    private BookCacheService bookCacheService;

    /**
     * 首页
     * @param request
     * @param pageNumber
     * @param pageSize
     * @param bookName
     * @param viewType
     * @param model
     * @return
     */
    @RequestMapping("/index")
    public String toBookIndex(HttpServletRequest request, Integer pageNumber,Integer pageSize,
                             String bookName, Integer viewType, Model model){
        String userAgent = request.getHeader("User-Agent");
        QueryParameters parameters = new QueryParameters();
        Paging paging = new Paging();
        if (pageNumber == null){
            pageNumber = 1;
        }
        if (pageSize == null){
            pageSize = 10;
        }
        paging.setPageNumber(pageNumber);
        paging.setPageSize(pageSize);
        parameters.setPaging(paging);
        BookParam bookParam = new BookParam();
        bookParam.setBookName(bookName);
        parameters.setParameters(bookParam);
        QueryResults<BookVO> bookPage = bookService.getBookPage(parameters);
        if (viewType == null){
            viewType = 1;
        }
        model.addAttribute("viewType", viewType);
        model.addAttribute("data", bookPage);
        if (DeviceUtil.checkAgentIsMobile(userAgent)){
            // 移动端
            return "mobile/book/book_list";
        }
        return "book/book_list";
    }

    /**
     * 首页
     * @param request
     * @param pageNumber
     * @param pageSize
     * @param bookName
     * @param viewType
     * @param model
     * @return
     */
    @RequestMapping("/")
    public String toBookList(HttpServletRequest request, Integer pageNumber,Integer pageSize,
                             String bookName, Integer viewType, Model model){
        String userAgent = request.getHeader("User-Agent");
        QueryParameters parameters = new QueryParameters();
        Paging paging = new Paging();
        if (pageNumber == null){
            pageNumber = 1;
        }
        if (pageSize == null){
            pageSize = 10;
        }
        paging.setPageNumber(pageNumber);
        paging.setPageSize(pageSize);
        parameters.setPaging(paging);
        BookParam bookParam = new BookParam();
        bookParam.setBookName(bookName);
        parameters.setParameters(bookParam);
        QueryResults<BookVO> bookPage = bookService.getBookPage(parameters);
        if (viewType == null){
            viewType = 1;
        }
        model.addAttribute("viewType", viewType);
        model.addAttribute("data", bookPage);
        if (DeviceUtil.checkAgentIsMobile(userAgent)){
            // 移动端
            return "mobile/book/book_list";
        }
        return "book/book_list";
    }

    /**
     * 书列表
     * @param request
     * @param pageNumber
     * @param pageSize
     * @param bookName
     * @param viewType
     * @param model
     * @return
     */
    @RequestMapping("/booklist")
    public String toBookList2(HttpServletRequest request, Integer pageNumber,Integer pageSize,
                              String bookName, Integer viewType, Model model){
        String userAgent = request.getHeader("User-Agent");
        QueryParameters<BookParam> parameters = new QueryParameters();
        Paging paging = new Paging();
        if (pageNumber == null){
            pageNumber = 1;
        }
        if (pageSize == null){
            pageSize = 10;
        }
        paging.setPageNumber(pageNumber);
        paging.setPageSize(pageSize);
        parameters.setPaging(paging);
        BookParam bookParam = new BookParam();
        bookParam.setBookName(bookName);
        parameters.setParameters(bookParam);
        QueryResults<BookVO> bookPage = bookService.getBookPage(parameters);
        if (viewType == null){
            viewType = 1;
        }
        model.addAttribute("viewType", viewType);
        model.addAttribute("data", bookPage);
        if (DeviceUtil.checkAgentIsMobile(userAgent)){
            // 移动端
            return "mobile/book/book_list";
        }
        return "book/book_list";
    }

    /**
     * 书详情
     * @param request
     * @param id
     * @param model
     * @return
     */
    @RequestMapping("/bookdetail/{id}")
    public String toBookDetail(HttpServletRequest request, @PathVariable("id") Long id, Model model){
        String userAgent = request.getHeader("User-Agent");
        // 书详情
        BookVO bookInfo = bookService.getBookById(id);
        model.addAttribute("book", bookInfo);
        // 首页码
        int firstSort = chapterService.getFirstSort(id);
        model.addAttribute("firstSort", firstSort);
        // 添加点击量
        bookService.addView(id);
        // 我的书架该书详情
        BookShelfVO bookShelfVO = bookShelfService.findByBookId(request, id);
        model.addAttribute("mySelfChapterVO", bookShelfVO);
        //检查该本小说是否保存在书架
        int i = bookService.isShelf(request, id);
        switch (i){
            case 0: model.addAttribute("presence",0);
                break;
            case 1: model.addAttribute("presence",1);
                break;
            default:
        }

        if (DeviceUtil.checkAgentIsMobile(userAgent)){
            // 移动端
            return "mobile/book/book_detail";
        }
        return "book/book_detail";
    }

    /**
     * 书正文
     * @param request
     * @param bookId
     * @param sort
     * @param model
     * @return
     */
    @GetMapping("/bookcontent/{id}/{sort}")
    public String toBookContent(HttpServletRequest request, @PathVariable("id") Long bookId, @PathVariable("sort") int sort, Model model){
        String userAgent = request.getHeader("User-Agent");
        BookVO bookVO = bookService.getBookById(bookId);

        ChapterVO chapterVO = chapterService.netChapter(bookId, sort);
        ChapterContentVO chapterContentVO = chapterContentService.getById(chapterVO.getContentId());

        bookShelfService.updateShelfChapter(request, bookId, sort);

        ChapterUpAndDownVO chapterUpAndDownVO = chapterService.getUpAndDown(bookId, sort);
        model.addAttribute("book", bookVO);
        model.addAttribute("chapter", chapterVO);
        model.addAttribute("content", chapterContentVO);
        model.addAttribute("chapterUpAndDownVO", chapterUpAndDownVO);
        if (DeviceUtil.checkAgentIsMobile(userAgent)){
            // 移动端
            return "mobile/book/book_content";
        }
        return "book/book_content";
    }

    /**
     * web返回一本小说所有章节
     * @param bookId
     * @param model
     * @return
     */
    @RequestMapping(value = "/bookchapter/{bookId}", method = RequestMethod.GET)
    public String chapterList(HttpServletRequest request,@PathVariable("bookId") Long bookId, Model model) {
        String userAgent = request.getHeader("User-Agent");
        if (DeviceUtil.checkAgentIsMobile(userAgent)){
            // 移动端
            return "redirect:/bookindex/"+bookId;
        }
        BookVO book = bookService.getBookById(bookId);
        BookShelfVO bookShelfVO = bookShelfService.findByBookId(request, bookId);
        List<ChapterVO> chapterList = chapterService.queryListByBookId(bookId);
        model.addAttribute("book",book);
        model.addAttribute("list",chapterList);
        model.addAttribute("mySelfChapterVO", bookShelfVO);
        model.addAttribute("size",chapterList.size());
        model.addAttribute("title",book.getBookName());
        return "book/book_chapter";
    }

    /**
     * 手机端小说章节页面
     * @param id
     * @param model
     * @return
     */
    @GetMapping("/bookindex/{id}")
    public String toBookChapterPage(HttpServletRequest request, @PathVariable("id") Long id, Model model){
        String userAgent = request.getHeader("User-Agent");
        if (!DeviceUtil.checkAgentIsMobile(userAgent)){
            // 移动端
            return "redirect:/bookchapter/"+id;
        }
        BookVO bookVO = bookService.getBookById(id);
        int pageSize = 20;
        int pageNo = 1;
        List<ChapterVO> chapterList = chapterService.queryListByBookId(id);
        model.addAttribute("book", bookVO);
        QueryResults<ChapterVO> queryResults = PageUtil.listToPage(pageNo, pageSize, chapterList);
        List<ChapterVO> chapterVOList = queryResults.getResults();
        model.addAttribute("chapterList", chapterVOList);
        int chapterNumber = chapterList.size();
        List<ChapterReturnVO> chapterReturnVOList = new ArrayList<>();
        int p = 1;
        for (int i=1;i <= chapterNumber;i++){
            if (i > 0 && i % pageSize == 0){
                ChapterReturnVO returnVO = new ChapterReturnVO();
                String title = "";
                int fromIndex = i - 19;
                title += "第" + fromIndex + "章-第"+ i + "章";
                returnVO.setPageNumber(p);
                returnVO.setTitle(title);
                chapterReturnVOList.add(returnVO);
                p++;
            }
            if (i == chapterNumber){
                ChapterReturnVO returnVO = new ChapterReturnVO();
                String title = "";
                int fromIndex = (chapterNumber / pageSize) * pageSize + 1;
                title += "第" + fromIndex + "章-第"+ i + "章";
                returnVO.setPageNumber(p);
                returnVO.setTitle(title);
                chapterReturnVOList.add(returnVO);
                p++;
            }

        }
        model.addAttribute("chapterReturnVOList", chapterReturnVOList);
        model.addAttribute("pageNo", pageNo);
        return "mobile/book/book_chapter";
    }

    /**
     *手机端小说章节页面
     * @param param bookId_pageNo格式
     * @param model
     * @return
     */
    @GetMapping("/bookchapters/{param}")
    public String toBookChapter(@PathVariable("param") String param, Model model){
        Long bookId = null;
        int pageNo = 1;
        if (StringUtils.isNotEmpty(param) && param.contains("_")){
            bookId = Long.valueOf(param.split("_")[0]);
            pageNo = Integer.valueOf(param.split("_")[1]);
        } else {
            throw new SelfException("传参有误");
        }

        BookVO bookVO = bookService.getBookById(bookId);
        int pageSize = 20;
        List<ChapterVO> chapterList = chapterService.queryListByBookId(bookId);
        model.addAttribute("book", bookVO);
        QueryResults<ChapterVO> queryResults = PageUtil.listToPage(pageNo, pageSize, chapterList);
        List<ChapterVO> chapterVOList = queryResults.getResults();
        model.addAttribute("chapterList", chapterVOList);
        int chapterNumber = chapterList.size();
        List<ChapterReturnVO> chapterReturnVOList = new ArrayList<>();
        int p = 1;
        for (int i=1;i <= chapterNumber;i++){
            if (i > 0 && i % pageSize == 0){
                ChapterReturnVO returnVO = new ChapterReturnVO();
                String title = "";
                int fromIndex = i - 19;
                title += "第" + fromIndex + "章-第"+ i + "章";
                returnVO.setPageNumber(p);
                returnVO.setTitle(title);
                chapterReturnVOList.add(returnVO);
                p++;
            }
            if (i % pageSize != 0 && i == chapterNumber){
                ChapterReturnVO returnVO = new ChapterReturnVO();
                String title = "";
                int fromIndex = (chapterNumber / pageSize) * pageSize + 1;
                title += "第" + fromIndex + "章-第"+ i + "章";
                returnVO.setPageNumber(p);
                returnVO.setTitle(title);
                chapterReturnVOList.add(returnVO);
                p++;
            }

        }
        model.addAttribute("chapterReturnVOList", chapterReturnVOList);
        model.addAttribute("pageNo", pageNo);
        return "mobile/book/book_chapter";
    }

    @GetMapping("/bookfile/download")
    @ResponseBody
    public void downloadBook(@RequestParam("id") Long id, HttpServletResponse response) throws IOException {
        BookCacheVO bookCacheVO = bookCacheService.getCacheByBookId(id);
        if (bookCacheVO == null){
            throw new SelfException("该书籍暂未缓存");
        }
        String fileName = bookCacheVO.getBookName();
        File file = new File(bookCacheVO.getAbsolutePath());
        if(file.exists()){ //判断文件父目录是否存在
            fileName = fileName + ".txt";
            response.setCharacterEncoding("utf-8");
            //设置响应内容的类型
            response.setContentType("text/plain");
            // response.setContentType("application/force-download");
            try {
                response.setHeader("Content-Disposition", "attachment;fileName=" +   java.net.URLEncoder.encode(fileName,"UTF-8"));
            } catch (UnsupportedEncodingException e) {
                throw new SelfException("转码异常");
            }
            byte[] buffer = new byte[1024];
            FileInputStream fis = null; //文件输入流
            BufferedInputStream bis = null;

            OutputStream os = null; //输出流
            try {
                os = response.getOutputStream();
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                int i = bis.read(buffer);
                while(i != -1){
                    os.write(buffer);
                    i = bis.read(buffer);
                }

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            log.info("----------file download---" + fileName);
            try {
                bis.close();
                fis.close();
            } catch (IOException e) {
                throw new SelfException("流关闭出错");
            }
        } else {
            throw new SelfException("该书籍不存在");
        }
    }
}